/** 
 * Project Name:jd-orm 
 * File Name:BaseDaoImpl.java 
 * Package Name:com.jd.orm.framework.core.dao.impl 
 * Date:2014-5-13下午2:20:51 
 * Copyright (c) 2014, liubing1@jd.com All Rights Reserved. 
 * 
 */  

package com.jd.orm.framework.core.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import net.sf.cglib.beans.BeanMap;

import com.jd.orm.framework.core.dao.IBaseDao;
import com.jd.orm.framework.core.dialect.Dialect;
import com.jd.orm.framework.core.entity.BaseEntity;
import com.jd.orm.framework.core.schema.SchemaColumn;
import com.jd.orm.framework.core.schema.SchemaInfo;
import com.jd.orm.framework.core.transaction.JdbcSession;
import com.jd.orm.framework.core.util.BeanSQLUtils;
import com.jd.orm.framework.core.util.PageResult;
import com.jd.orm.framework.core.util.QueryCriteria;
import com.jd.orm.framework.core.util.StringUtil;
import com.jd.orm.framework.core.validate.DefaultOrmValidateImpl;
import com.jd.orm.framework.core.validate.IOrmValidate;
import com.jd.orm.framework.core.validate.JDOrmValidate;

/** 
 * ClassName: BaseDaoImpl <br/> 
 * Function: TODO ADD FUNCTION. <br/> 
 * Reason: TODO ADD REASON. <br/> 
 * date: 2014-5-13 下午2:20:51 <br/> 
 * 
 * @author  liubing1@jd.com 
 * @version  
 * @since up JDK 1.5 
 */

public class BaseDaoImpl<T extends BaseEntity> implements IBaseDao<T> {
	
	private Class<T> entityClass;
	
	public BaseDaoImpl(){
		if (ParameterizedType.class.isAssignableFrom(getClass()
				.getGenericSuperclass().getClass())) {
			Type[] actualTypeArguments = ((ParameterizedType) getClass()
					.getGenericSuperclass()).getActualTypeArguments();
			entityClass = (Class<T>) actualTypeArguments[0];
		}
	}
	public void doCreateEntity(JdbcSession jdbcSession, T t) throws Exception {
		// TODO Auto-generated method stub
		SchemaInfo schemaInfo=t.getSchemaInfo();
		String insertSql=BeanSQLUtils.get_sql_insert(schemaInfo, JdOrmTemplate.doGetDialet(jdbcSession.getConnection()));
		Boolean flag=true;
		for(SchemaColumn schemaColumn:schemaInfo.getColumns()){
			if(StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())&&!schemaColumn.isNullable()){
				throw new Exception("字段"+schemaColumn.getFieldName()+"必填");
			}
			if(!StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())&&!StringUtil.isNullOrEmpty(schemaColumn.getTypeLength())){
				flag=JDOrmValidate.validateLength(schemaColumn.getFieldValue()+"", schemaColumn.getTypeLength());
				if(!flag){
					throw new Exception("字段"+schemaColumn.getFieldName()+"长度过长，超过最大值:"+schemaColumn.getTypeLength());
				}
			}
			
			if(!StringUtil.isNullOrEmpty(schemaColumn.getValidateType())&&!StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())){
				flag=JDOrmValidate.defaultValidate(schemaColumn.getValidateType(), schemaColumn.getFieldValue()+"");
				if(!flag){
					throw new Exception("字段"+schemaColumn.getFieldName()+"验证不通过，验证类型为:"+schemaColumn.getValidateType());
				}
			}
		}
		JdOrmTemplate.execute(jdbcSession.getConnection(),insertSql, null);
	}

	public void doCreateEntity(JdbcSession jdbcSession, T t,
			DefaultOrmValidateImpl defaultOrmValidateImpl) throws Exception {
		// TODO Auto-generated method stub
		SchemaInfo schemaInfo=t.getSchemaInfo();
		String insertSql=BeanSQLUtils.get_sql_insert(schemaInfo, JdOrmTemplate.doGetDialet(jdbcSession.getConnection()));
		Boolean flag=true;
		IOrmValidate ormValidate=defaultOrmValidateImpl;
		for(SchemaColumn schemaColumn:schemaInfo.getColumns()){
			if(StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())&&!schemaColumn.isNullable()){
				throw new Exception("字段"+schemaColumn.getFieldName()+"必填");
			}
			if(!StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())&&!StringUtil.isNullOrEmpty(schemaColumn.getTypeLength())){
				flag=JDOrmValidate.validateLength(schemaColumn.getFieldValue()+"", schemaColumn.getTypeLength());
				if(!flag){
					throw new Exception("字段"+schemaColumn.getFieldName()+"长度过长，超过最大值:"+schemaColumn.getTypeLength());
				}
			}
			if(!StringUtil.isNullOrEmpty(schemaColumn.getValidateType())&&!StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())){
				flag=JDOrmValidate.defaultValidate(schemaColumn.getValidateType(), schemaColumn.getFieldValue()+"");
				if(!flag){
					throw new Exception("字段"+schemaColumn.getFieldName()+"验证不通过，验证类型为:"+schemaColumn.getValidateType());
				}
			}
			if(!ormValidate.UserValidate(schemaColumn.getValidateType(), schemaColumn.getFieldValue()+"")){
				throw new Exception("字段"+schemaColumn.getFieldName()+"验证不通过");
			}
		}
		JdOrmTemplate.execute(jdbcSession.getConnection(),insertSql, null);
	}

	public void doCreateBySql(JdbcSession jdbcSession, String sql,
			Object... params) throws Exception {
		// TODO Auto-generated method stub
		JdOrmTemplate.execute(jdbcSession.getConnection(),sql, params);
	}

	public void doUpdateEntity(JdbcSession jdbcSession, T t) throws Exception {
		// TODO Auto-generated method stub
		SchemaInfo schemaInfo=t.getSchemaInfo();
		String updatesql=BeanSQLUtils.get_sql_update(schemaInfo, JdOrmTemplate.doGetDialet(jdbcSession.getConnection()));
		Boolean flag=true;
		for(SchemaColumn schemaColumn:schemaInfo.getColumns()){
			if(StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())&&!schemaColumn.isNullable()){
				throw new Exception("字段"+schemaColumn.getFieldName()+"必填");
			}
			if(!StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())&&!StringUtil.isNullOrEmpty(schemaColumn.getTypeLength())){
				flag=JDOrmValidate.validateLength(schemaColumn.getFieldValue()+"", schemaColumn.getTypeLength());
				if(!flag){
					throw new Exception("字段"+schemaColumn.getFieldName()+"长度过长，超过最大值:"+schemaColumn.getTypeLength());
				}
			}
			
			if(!StringUtil.isNullOrEmpty(schemaColumn.getValidateType())&&!StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())){
				flag=JDOrmValidate.defaultValidate(schemaColumn.getValidateType(), schemaColumn.getFieldValue()+"");
				if(!flag){
					throw new Exception("字段"+schemaColumn.getFieldName()+"验证不通过，验证类型为:"+schemaColumn.getValidateType());
				}
			}
		}
		JdOrmTemplate.execute(jdbcSession.getConnection(),updatesql, null);
	}

	public void doUpdateEntity(JdbcSession jdbcSession, T t,
			DefaultOrmValidateImpl defaultOrmValidateImpl) throws Exception {
		// TODO Auto-generated method stub
		SchemaInfo schemaInfo=t.getSchemaInfo();
		String updatesql=BeanSQLUtils.get_sql_update(schemaInfo, JdOrmTemplate.doGetDialet(jdbcSession.getConnection()));
		Boolean flag=true;
		IOrmValidate ormValidate=defaultOrmValidateImpl;

		for(SchemaColumn schemaColumn:schemaInfo.getColumns()){
			if(StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())&&!schemaColumn.isNullable()){
				throw new Exception("字段"+schemaColumn.getFieldName()+"必填");
			}
			if(!StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())&&!StringUtil.isNullOrEmpty(schemaColumn.getTypeLength())){
				flag=JDOrmValidate.validateLength(schemaColumn.getFieldValue()+"", schemaColumn.getTypeLength());
				if(!flag){
					throw new Exception("字段"+schemaColumn.getFieldName()+"长度过长，超过最大值:"+schemaColumn.getTypeLength());
				}
			}
			
			if(!StringUtil.isNullOrEmpty(schemaColumn.getValidateType())&&!StringUtil.isNullOrEmpty(schemaColumn.getFieldValue())){
				flag=JDOrmValidate.defaultValidate(schemaColumn.getValidateType(), schemaColumn.getFieldValue()+"");
				if(!flag){
					throw new Exception("字段"+schemaColumn.getFieldName()+"验证不通过，验证类型为:"+schemaColumn.getValidateType());
				}
			}
			if(!ormValidate.UserValidate(schemaColumn.getValidateType(), schemaColumn.getFieldValue()+"")){
				throw new Exception("字段"+schemaColumn.getFieldName()+"验证不通过");
			}
		}
		JdOrmTemplate.execute(jdbcSession.getConnection(),updatesql, null);
	}

	public void doUpdateBySql(JdbcSession jdbcSession, String sql,
			Object... params) throws Exception {
		// TODO Auto-generated method stub
		JdOrmTemplate.execute(jdbcSession.getConnection(),sql, params);
	}

	public void doRemoveEntity(JdbcSession jdbcSession, T t) throws Exception {
		// TODO Auto-generated method stub
		SchemaInfo schemaInfo=t.getSchemaInfo();
		String deletesql=BeanSQLUtils.get_sql_delete(schemaInfo, JdOrmTemplate.doGetDialet(jdbcSession.getConnection()));
		JdOrmTemplate.execute(jdbcSession.getConnection(),deletesql, null);
	}

	public void doRemoveBySql(JdbcSession jdbcSession, String sql,
			Object... params) throws Exception {
		// TODO Auto-generated method stub
		JdOrmTemplate.execute(jdbcSession.getConnection(),sql, params);
	}

	public T findById(JdbcSession jdbcSession, Serializable id)
			throws Exception {
		// TODO Auto-generated method stub
		entityClass.newInstance();
		if(entityClass.newInstance() instanceof BaseEntity){
			BaseEntity baseEntity=entityClass.newInstance();
			SchemaInfo schemaInfo=baseEntity.getSchemaInfo();
			Dialect dialect=JdOrmTemplate.doGetDialet(jdbcSession.getConnection());
			String sql=BeanSQLUtils.get_sql_select_object(schemaInfo,dialect );
			return JdOrmTemplate.queryAsObject(jdbcSession.getConnection(),entityClass, sql, id);
		}
		return null;
	}

	public List<T> findAll(JdbcSession jdbcSession) throws Exception {
		// TODO Auto-generated method stub
		if(entityClass.newInstance() instanceof BaseEntity){
			BaseEntity baseEntity=entityClass.newInstance();
			SchemaInfo schemaInfo=baseEntity.getSchemaInfo();
			String sql=BeanSQLUtils.get_sql_select_all_object(schemaInfo, JdOrmTemplate.doGetDialet(jdbcSession.getConnection()));
			return JdOrmTemplate.queryAsList(jdbcSession.getConnection(),entityClass, sql, null);//根据主键查询
		}
		return null;
	}

	public List<T> findByBean(JdbcSession jdbcSession, T t) throws Exception {
		// TODO Auto-generated method stub
		SchemaInfo schemaInfo=t.getSchemaInfo();
		Map<String, Object>params=BeanMap.create(t);
		String sql=BeanSQLUtils.get_complex_sql_select_object(schemaInfo, JdOrmTemplate.doGetDialet(jdbcSession.getConnection()), params, null, null);
		return JdOrmTemplate.queryAsList(jdbcSession.getConnection(),entityClass, sql, params);//根据主键查询
	}

	public List<T> findByMap(JdbcSession jdbcSession, Map<String, Object> params)
			throws Exception {
		// TODO Auto-generated method stub
		if(entityClass.newInstance() instanceof BaseEntity){
			BaseEntity baseEntity=entityClass.newInstance();
			SchemaInfo schemaInfo=baseEntity.getSchemaInfo();
			String sql=BeanSQLUtils.get_complex_sql_select_object(schemaInfo, JdOrmTemplate.doGetDialet(jdbcSession.getConnection()), params, null, null);
			return JdOrmTemplate.queryAsList(jdbcSession.getConnection(),entityClass, sql, null);//根据主键查询
		}
		return null;
	}

	public List<T> findReturnClassByParamsAndSql(JdbcSession jdbcSession,
			String sql, Class<?> returnentityclass, Object... params)
			throws Exception {
		// TODO Auto-generated method stub
		return JdOrmTemplate.queryAsList(jdbcSession.getConnection(),entityClass, sql, params);
	}

	public Object findReturnObjectByParamsAndSql(JdbcSession jdbcSession,
			String sql, Class<?> cls, Object... params) throws Exception {
		// TODO Auto-generated method stub
		return JdOrmTemplate.queryAsObject(jdbcSession.getConnection(),cls, sql, params);
	}

	public Integer findAsInt(JdbcSession jdbcSession, String sql,
			Object... parameters) throws Exception {
		// TODO Auto-generated method stub
		return JdOrmTemplate.queryAsInt(jdbcSession.getConnection(),sql, parameters);
	}

	public Long findAsLong(JdbcSession jdbcSession, String sql,
			Object... parameters) throws Exception {
		// TODO Auto-generated method stub
		return JdOrmTemplate.queryAsLong(jdbcSession.getConnection(),sql, parameters);
	}

	public Float findAsFloat(JdbcSession jdbcSession, String sql,
			Object... parameters) throws Exception {
		// TODO Auto-generated method stub
		return JdOrmTemplate.queryAsFloat(jdbcSession.getConnection(),sql, parameters);
	}

	public String findAsString(JdbcSession jdbcSession, String sql,
			Object... parameters) throws Exception {
		// TODO Auto-generated method stub
		return JdOrmTemplate.queryAsString(jdbcSession.getConnection(),sql, parameters);
	}

	public Map<String, Object> findAsMap(JdbcSession jdbcSession, String sql,
			Object... parameters) throws Exception {
		// TODO Auto-generated method stub
		return JdOrmTemplate.queryAsMap(jdbcSession.getConnection(),sql, parameters);
	}

	public PageResult<T> findByCriteria(JdbcSession jdbcSession,
			QueryCriteria queryCriteria) throws Exception {
		// TODO Auto-generated method stub
		if(entityClass.newInstance() instanceof BaseEntity){
			BaseEntity baseEntity=entityClass.newInstance();
			SchemaInfo schemaInfo=baseEntity.getSchemaInfo();
			String orderField="";
	    	if(!BeanSQLUtils.validateTransient(schemaInfo.getColumns(), queryCriteria.getOrderField())){
	    		if(!StringUtil.isNullOrEmpty(queryCriteria.getOrderField())){
		    		orderField=queryCriteria.getOrderField().substring(0, queryCriteria.getOrderField().indexOf("name"));
	    		}
	    	}else{
	    		if(!StringUtil.isNullOrEmpty(queryCriteria.getOrderField())){
	    			orderField=queryCriteria.getOrderField();
	    		}
	    		
	    	}
	    	orderField=BeanSQLUtils.getOrderField(schemaInfo.getColumns(), orderField);
			String sql=BeanSQLUtils.get_complex_sql_select_object(schemaInfo, JdOrmTemplate.doGetDialet(jdbcSession.getConnection()), queryCriteria.getQueryCondition(), orderField, queryCriteria.getOrderDirection());
	    	return JdOrmTemplate.queryAsPagelist(jdbcSession.getConnection(),entityClass, sql, queryCriteria);
		}
		return null;
	}
	public int[] executeBatch(JdbcSession jdbcSession, String sql,
			List<Object[]> parameters) throws Exception {
		// TODO Auto-generated method stub
		return JdOrmTemplate.executeBatch(jdbcSession.getConnection(), sql, parameters);
	}
	
	
	
}
